﻿using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;

namespace 串口助手
{
    /// <summary>
    /// 处理自动发送的命令和消息
    /// </summary>
    class AutoTx
    {
        [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern int memcmp(byte[] b1, byte[] b2, long count);

        /// <summary>
        /// 自动发送类
        /// </summary>
        public class AutoTxClass_t
        {
            public byte[] rx; // 接收的字节数组
            public byte[] tx; // 发送的字节数组
        };

        private List<AutoTxClass_t> ListAutoTx = new List<AutoTxClass_t>(); // 存储自动发送规则的列表

        private Thread receiveThread;
        private volatile bool running = true;

        /// <summary>
        /// 更新命令规则
        /// </summary>
        /// <param name="cmd">命令数组</param>
        /// <param name="DataType">数据类型</param>
        /// <param name="MsgTailType">消息尾部类型</param>
        public void CmdUpdate(string[] cmd, string DataType, string MsgTailType)
        {
            DataTypeConversion dataType = new DataTypeConversion();
            ListAutoTx.Clear(); // 清空当前规则列表

            foreach (string p in cmd)
            {
                if (string.IsNullOrWhiteSpace(p) || !p.Contains('$'))
                    continue; // 跳过空命令或不包含 '$' 的命令

                string[] temp = p.Split('$');
                if (temp[0] == "" || temp[1] == "")
                {
                    MessageBox.Show("请检查：" + p + "！", "自动下发的规则异常");
                    return; // 规则异常，弹出提示并返回
                }

                AutoTxClass_t class_T = new AutoTxClass_t
                {
                    rx = dataType.StringToByte(DataType, temp[0]), // 转换接收命令
                    tx = dataType.StringToByte(DataType, temp[1])  // 转换发送命令
                };

                if (class_T.rx == null || class_T.tx == null)
                {
                    MessageBox.Show("请检查：" + p + "！", "自动下发的规则异常");
                    return; // 规则异常，弹出提示并返回
                }

                dataType.ByteAddMsgTail(MsgTailType, ref class_T.rx); // 添加消息尾部
                ListAutoTx.Add(class_T); // 添加到规则列表
            }
        }

        /// <summary>
        /// 根据接收到的字节数组获取对应的发送消息
        /// </summary>
        /// <param name="rx">接收到的字节数组</param>
        /// <param name="length">字节数组长度</param>
        /// <returns>对应的发送字节数组，如果没有匹配则返回 null</returns>
        public byte[] GetTxMsg(byte[] rx, int length)
        {
            foreach (AutoTxClass_t p in ListAutoTx)
            {
                if (p.rx.Length != length)
                    continue; // 跳过长度不匹配的项
                if (memcmp(p.rx, rx, p.rx.Length) == 0)
                    return p.tx; // 找到匹配的发送消息并返回
            }
            return null; // 没有找到匹配项，返回 null
        }

        /// <summary>
        /// 开始接收数据
        /// </summary>
        public void StartReceiving()
        {
            running = true;
            receiveThread = new Thread(ReceiveData)
            {
                IsBackground = true // 设置为后台线程
            };
            receiveThread.Start();
        }

        /// <summary>
        /// 停止接收数据
        /// </summary>
        public void StopReceiving()
        {
            running = false;
            if (receiveThread != null && receiveThread.IsAlive)
            {
                receiveThread.Join(); // 等待线程结束
            }
        }

        /// <summary>
        /// 接收数据的线程方法
        /// </summary>
        private void ReceiveData()
        {
            while (running)
            {
                // 模拟接收数据的逻辑
                // 实际上你需要从串口或其他输入源读取数据
                byte[] receivedData = SimulateReceive(); // 替换为实际的接收逻辑
                if (receivedData != null)
                {
                    // 处理接收到的数据
                    ProcessReceivedData(receivedData);
                }
                Thread.Sleep(100); // 适当的等待时间，避免过于频繁的循环
            }
        }

        /// <summary>
        /// 处理接收到的数据
        /// </summary>
        /// <param name="rx">接收到的字节数组</param>
        private void ProcessReceivedData(byte[] rx)
        {
            // 处理接收到的数据
            // 这里可以调用 GetTxMsg 方法来获取对应的发送消息
            byte[] txMsg = GetTxMsg(rx, rx.Length);
            if (txMsg != null)
            {
                // 发送响应消息
                SendTxMsg(txMsg);
            }
        }

        /// <summary>
        /// 模拟接收数据
        /// </summary>
        /// <returns>接收到的字节数组</returns>
        private byte[] SimulateReceive()
        {
            // 这里可以模拟接收数据的逻辑
            // 例如，返回一些伪造的数据
            return new byte[] { 0x12, 0x25 }; // 示例数据
        }

        /// <summary>
        /// 发送消息的逻辑
        /// </summary>
        /// <param name="txMsg">要发送的字节数组</param>
        private void SendTxMsg(byte[] txMsg)
        {
            // 发送消息的逻辑
            // 可以调用其他类的方法来实现
        }
    }
}
